#!/bin/sh

config() {
    user=st
    hostname=archlinux
    tz=Europe/Moscow
    
    device=/dev/nvme0n1
    
    rpass="archlinux"
    upass="archlinux"
    
    locales=(
        'en_US.UTF-8'
        'ru_RU.UTF-8'
    )
    
    main_locale=0
    
    hooks="base udev autodetect modconf block filesystems keyboard resume fsck"
    # modules=""
    
    ######################### --- FILES --- ###############################
    
    # mpath="/mnt"
    mpath="$HOME/alis/test"
    achroot="arch-chroot $mpath"
    
    lgen_path="etc/locale.gen"
    lconf_path="etc/locale.conf"
    
    hostname_path="etc/hostname"
    hosts_file="etc/hosts"
    swapfile_path="swapfile"
    fstab_path="etc/fstab"
    sudoers_path="etc/sudoers"
    mkinitcpio_path="etc/mkinitcpio.conf"
    grub_path="etc/default/grub"
    
    
    lgen_path=$mpath/$lgen_path
    lconf_path=$mpath/$lconf_path
    
    hostname_path=$mpath/$hostname_path
    hosts_file=$mpath/$hosts_file
    swapfile_path=$mpath/$swapfile_path
    fstab_path=$mpath/$fstab_path
    sudoers_path=$mpath/$sudoers_path
    mkinitcpio_path=$mpath/$mkinitcpio_path
    grub_path=$mpath/$grub_path
    
    ######################### --- PACKAGES --- ###############################
    
    base="base base-devel linux linux-firmware"
    xorg="xorg xorg-drivers xorg-xinit"
    shell="zsh"
    grub="grub efibootmgr"
    dm="sddm"
    custom="termite wget vim iwd networkmanager i3 git neofetch python"
    
    pacstrap_list="$base $xorg $shell $grub $dm $custom"
    
    ########################   --- GRUB ---   ################################
    
    boot_inst="grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot"
    boot_conf="grub-mkconfig -o /boot/grub/grub.cfg"

}

config

strings() {
    RED="$(printf '\033[31m')"
    GREEN="$(printf '\033[32m')"
    ORANGE="$(printf '\033[33m')"
    BLUE="$(printf '\033[34m')"
    MAGENTA="$(printf '\033[35m')"
    CYAN="$(printf '\033[36m')"
    WHITE="$(printf '\033[37m')"
    BOLD="$(printf '\033[1m')"
    
    nl() { printf "\n$1\n\n"; }
    clr() { printf "${1}${2}${WHITE}"; }
    
    white() { clr $WHITE "$1"; }
    red() { clr $RED "$1"; }
    green() { clr $GREEN "$1"; }
    blue() { clr $BLUE "$1"; }
    cyan() { clr $CYAN "$1"; }
    orange() { clr $ORANGE "$1"; }
    magenta() { clr $MAGENTA "$1"; }
    
    askm() { magenta "$(nl "$cont_msg")"; }
    
    ask() {
        read bool
        printf "\n"
    
        if [[ -z $bool ]] || [[ $bool == 'y' ]]; then
            $1
        else
            $2
        fi
    }
    
    
    cont_msg="Continue? [y/N] "
    
    warn_msg="Attention! Edit alais.sh before run it!"
    
    lsblk_msg="Listing block devices"
    
    mnt_msg="Formatting & Mounting partitions"
    install_msg="Installing packages in $mpath"
    create_user_msg="Creating user"
    passwd_msg="Setting passwords for root and $(magenta "$user")"
    genfs_msg="Writing genfstab partition scheme"
    
    tz_msg="Configuring timezone"
    locales_msg="Configuring locales"
    hostname_msg="Writing hostname"
    
    sudo_msg="Writing sudoers file"
    ramdisk_msg="Building initial ramdisk evironment"
    ctl_msg="Enabling services"
    
    grub_msg="Installing GRUB to -> $(magenta "$mpath/boot")"

    swap_created_msg="Swap file created successfully"
    grubfile_msg="Editing $grub_path to enable swapfile hibernation"
}

strings

echo_conf() {
    echo "Username: $(orange $user)"
    echo "Hostname: $(orange $hostname)"
    echo ""
    echo "Device: $(orange $device)"
    echo "Timezone: $(orange $tz)"
    
    nl "LANG: $(orange ""${locales[$main_locale]}"")"

    echo "Locales:"
    echo

    for i in "${locales[@]}"; do
	echo "$(orange $i)"
    done

    askm
    ask true exit  
}

mount_dev() {
    timedatectl set-ntp true
    
    boot="$device$boot"
    root="$device$root"
    home="$device$home"
    
    mkfs.fat -F32 $boot
    mkfs.ext4 $root
    mkfs.ext4 $home

    mount $root $mpath 
    mkdir $mpath/{boot,home}

    mount $boot $mpath/boot
    mount $home $mpath/home
}

pacstrap_install() { 
    clr_list="${WHITE}$base ${ORANGE}$xorg ${BLUE}$grub ${GREEN}$shell $dm ${CYAN}$custom"
    clr_list="${clr_list//$' '/'\n'}"

    do_add_pkg() { read -p "Enter your packages: " add_pkg; }

    nl "$(red "Packages to install:")"
    sleep 1
    nl $clr_list

    magenta "Add some another packages? [y/N] "
    ask do_add_pkg true 

    pacstrap $mpath $pacstrap_list $add_pkg; 
}

create_user() { $achroot useradd -m -g users -G wheel -s /bin/$shell $user; }

set_passwd() {
    echo "root:$rpass" | chpasswd -R $mpath
    echo "$user:$upass" | chpasswd -R $mpath 
}

write_genfs() {
    local res=$(genfstab -U $mpath)
    echo $res >> $fstab_path
}

set_tz() {
    ln -sf /usr/share/zoneinfo/$tz /etc/localtime
    $achroot hwclock --systohc
}

set_locales() {

    echo '' > $locale_gen

    for i in "${locales[@]}"; do
	echo "$i UTF-8" >> $lgen_path
    done
    
    echo "LANG=${locales[$main_locale]}" > $lconf_path

    $achroot locale-gen
}

set_hostname() { echo $hostname > $hostname_path; } 

write_sudoers() { echo "%wheel ALL=(ALL) ALL" >> $sudoers_path; }

kernel_setup() {
    if [[ -n $hooks ]]; then
        default_hooks="HOOKS=(base udev autodetect modconf block filesystems keyboard fsck)"
        new_hooks="HOOKS=($hooks)"

        sed -i "s/$default_hooks/$new_hooks/" $mkinitcpio_path
    fi

    $achroot mkinitcpio -P; 
}

ctl_enable() {
    ctl="systemctl enable"
    nm="NetworkManager"
    
    $achroot $ctl $nm
    $achroot $ctl $dm
}

grub_install() { $achroot $boot_inst; $achroot $boot_conf; }


with_msg() {
    nl "$(orange "[[ $1 ]]")"
    
    sleep $3 
    $2
}


do_additional_stuff() {
    install_hosts() { wget https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts -O $hosts_file; }

    create_swapfile() {
        orange "Enter swapfile size in GB: "
        read size

        fallocate -l ${size}G $swapfile_path
        chmod 600 $swapfile_path
        mkswap $swapfile_path
        swapon $swapfile_path
        echo "$swapfile_path swap swap defaults 0 0" | tee -a $fstab_path
        
        nl "$(green "$swap_created_msg")"
        sleep 1

        uuid=$(sudo findmnt -no SOURCE,UUID -T $swapfile_path | awk '{ print $2} ')
        offset=$(sudo filefrag -v $swapfile_path | awk '{ if($1=="0:"){print $4} }' | awk -F. '{ print $1} ')

        echo "UUID: $( orange "$uuid")"
        echo "Offset: $( orange "$offset")"

        sleep 1
    }

    write_grub () {
        line=$(cat $grub_path | grep -n 'GRUB_CMDLINE_LINUX_DEFAULT' | awk -F: ' { print $1 }')
        to="GRUB_CMDLINE_LINUX_DEFAULT=\"resume=UUID=${uuid} resume_offset=${offset} loglevel=3 quiet\""

        copy_file=${grub_path}.bak
        awk -v to="$to" -v line="$line" '{ if (NR == line) print to; else print $0; }' $grub_path >> $copy_file 
        mv $copy_file $grub_path
    }

    green "\nInstall hosts file and write -> $(magenta "$hosts_file")$(green "? [y/N]") "
    ask install_hosts true

    with_msg "Creating swapfile in -> $( magenta "$swapfile_path")" create_swapfile 2
    with_msg "$grubfile_msg" write_grub 2 
}


warn() { 
    printf "$(magenta "->") $(red "$warn_msg") $(magenta "<-")\n"; 
    
    askm
    ask true exit
}

lst_devs() { lsblk $device; white "\n\n"; }

open_cfdisk() {
    cf_run() { sudo cfdisk $device; }

    ask_msg="\nOpen cfdisk? [y/N] "

    cyan "$ask_msg"
    ask cf_run
}

read_dev() {
    msg="${WHITE}Enter your partitions sub-path:
[e.g: /dev/nvme0n1$(red p3), /dev/sd$(red 3)]\n\n"

    orange "$msg"

    read -p "$(orange boot): " boot
    read -p "$(orange root): " root
    read -p "$(orange home): " home
}

####################### --- INSTALLAION --- #############################

main() {
    warn
    echo_conf
    
    open_cfdisk
    
    with_msg "$lsblk_msg" lst_devs 1 
    
    read_dev
    
    with_msg "$mnt_msg" mount_dev 1
    with_msg "$install_msg" pacstrap_install 1
    with_msg "$create_user_msg" create_user 1
    with_msg "$passwd_msg" set_passwd 1
    with_msg "$genfs_msg" write_genfs 1
    
    with_msg "$tz_msg" set_tz 1
    with_msg "$locales_msg" set_locales 1
    with_msg "$hostname_msg" set_hostname 1
    
    with_msg "$sudo_msg" write_sudoers 1
    with_msg "$ramdisk_msg" kernel_setup 1
    with_msg "$ctl_msg" ctl_enable 1
    with_msg "$grub_msg" grub_install 1
    
    do_additional_stuff
    
    nl "$(green "Installation completed!")"
    sleep 2 
    
    magenta "Reboot now? [y/N] "
    ask reboot exit
}    

main
